Use QDataStream for Geogrid-Viewer binary files
authorRalf Horstmann <ralf+github@ackstorm.de>
Sat, 16 Jan 2016 13:50:09 +0000 (14:50 +0100)
committerRalf Horstmann <ralf+github@ackstorm.de>
Sun, 17 Jan 2016 11:50:04 +0000 (12:50 +0100)
This eliminates the need to do the manual endianess handling
and converting binary data into a double. Works on SPARC64
as well (big endian).

ggv_bin.cc

index 1d64f4da81d579013b89fdc2216e1b4607e313da..9f25f742d7ea64e04bc18abce06b66f2002a9f0e 100644 (file)
@@ -36,36 +36,32 @@ static QString read_fname;
  ***************************************************************************/
 
 static void
-ggv_bin_read_bytes(QFile& file, QByteArray& buf, qint64 size, const char* descr = NULL)
+ggv_bin_read_bytes(QDataStream& stream, QByteArray& buf, qint64 len, const char* descr = NULL)
 {
-  if (size > file.size())
-    fatal(MYNAME ": Read size error (%s)\n", descr ? descr : "");
-  buf = file.read(size);
-  if (buf.size() < size)
+  buf.resize(len);
+  if (stream.readRawData(buf.data(), len) != len || stream.status() != QDataStream::Ok)
     fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
 }
 
 static quint16
-ggv_bin_read16(QFile& file, const char* descr = NULL)
+ggv_bin_read16(QDataStream& stream, const char* descr = NULL)
 {
-  QByteArray buf;
   quint16 res;
-
-  ggv_bin_read_bytes(file, buf, 2, descr);
-  res = qFromLittleEndian<quint16>((const uchar*)buf.constData());
+  stream >> res;
+  if (stream.status() != QDataStream::Ok)
+    fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
   if (global_opts.debug_level > 1)
     qDebug("ovl: %-15s %5u (0x%04x)", descr, res, res);
   return res;
 }
 
 static quint32
-ggv_bin_read32(QFile& file, const char* descr = NULL)
+ggv_bin_read32(QDataStream& stream, const char* descr = NULL)
 {
-  QByteArray buf;
   quint32 res;
-
-  ggv_bin_read_bytes(file, buf, 4, descr);
-  res = qFromLittleEndian<quint32>((const uchar*)buf.constData());
+  stream >> res;
+  if (stream.status() != QDataStream::Ok)
+    fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
   if (global_opts.debug_level > 1) {
     if ((res & 0xFFFF0000) == 0) 
       qDebug("ovl: %-15s %5u (0x%08x)", descr, res, res);
@@ -76,40 +72,33 @@ ggv_bin_read32(QFile& file, const char* descr = NULL)
 }
 
 static void
-ggv_bin_read_text16(QFile& file, QByteArray& buf, const char* descr = NULL)
+ggv_bin_read_text16(QDataStream& stream, QByteArray& buf, const char* descr = NULL)
 {
-  quint16 len;
-  
-  len = ggv_bin_read16(file, descr);
-  ggv_bin_read_bytes(file, buf, len, descr);
+  quint16 len = ggv_bin_read16(stream, descr);
+  ggv_bin_read_bytes(stream, buf, len, descr);
   buf[len] = 0;
   if (global_opts.debug_level > 1)
     qDebug() << "ovl: text =" << QString::fromLatin1(buf.constData()).simplified();
 }
 
 static void
-ggv_bin_read_text32(QFile& file, QByteArray& buf, const char* descr = NULL)
+ggv_bin_read_text32(QDataStream& stream, QByteArray& buf, const char* descr = NULL)
 {
-  quint32 len;
-  
-  len = ggv_bin_read32(file, descr);
-  ggv_bin_read_bytes(file, buf, len, descr);
+  quint32 len = ggv_bin_read32(stream, descr);
+  ggv_bin_read_bytes(stream, buf, len, descr);
   buf[len] = 0;
   if (global_opts.debug_level > 1)
     qDebug() << "ovl: text =" << QString::fromLatin1(buf.constData()).simplified();
 }
 
 static double
-ggv_bin_read_double(QFile& file, const char* descr = NULL)
+ggv_bin_read_double(QDataStream& stream, const char* descr = NULL)
 {
-  QByteArray buf;
-  quint64 tmp;
-  const double *res;
-
-  ggv_bin_read_bytes(file, buf, sizeof(double), descr);
-  tmp = qFromLittleEndian<quint64>((const uchar*)buf.constData());
-  res = reinterpret_cast<const double*>(&tmp);
-  return *res;
+  double res;
+  stream >> res;
+  if (stream.status() != QDataStream::Ok)
+    fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
+  return res;
 }
 
 /***************************************************************************
@@ -117,7 +106,7 @@ ggv_bin_read_double(QFile& file, const char* descr = NULL)
  ***************************************************************************/
 
 static void
-ggv_bin_read_v2(QFile& file)
+ggv_bin_read_v2(QDataStream& stream)
 {
   QByteArray buf;
   QString track_name;
@@ -132,26 +121,26 @@ ggv_bin_read_v2(QFile& file)
   quint64 entry_pos;
 
   // header length is usually either 0x90 or 0x00
-  header_len = ggv_bin_read16(file, "map name len");
+  header_len = ggv_bin_read16(stream, "map name len");
   if (header_len > 0) {
-    ggv_bin_read_bytes(file, buf, header_len, "map name");
+    ggv_bin_read_bytes(stream, buf, header_len, "map name");
     buf.remove(0,4);
     buf.append('\0');
     if (global_opts.debug_level > 1)
       qDebug() << "ovl: name =" << buf.constData();
   }
 
-  while (!file.atEnd()) {
+  while (!stream.atEnd()) {
     track_name.clear();
 
     if (global_opts.debug_level > 1)
-      qDebug("------------------------------------ 0x%llx", file.pos());
+      qDebug("------------------------------------ 0x%llx", stream.device()->pos());
 
-    entry_pos = file.pos();
-    entry_type = ggv_bin_read16(file, "entry type");
-    ggv_bin_read16(file, "entry group");
-    ggv_bin_read16(file, "entry zoom");
-    entry_subtype = ggv_bin_read16(file, "entry subtype");
+    entry_pos = stream.device()->pos();
+    entry_type = ggv_bin_read16(stream, "entry type");
+    ggv_bin_read16(stream, "entry group");
+    ggv_bin_read16(stream, "entry zoom");
+    entry_subtype = ggv_bin_read16(stream, "entry subtype");
 
     switch (entry_subtype) {
     case 0x01:
@@ -159,7 +148,7 @@ ggv_bin_read_v2(QFile& file)
       break;
     case 0x10:
       // text with 32 bit length field follows
-      ggv_bin_read_text32(file, buf, "text len");
+      ggv_bin_read_text32(stream, buf, "text len");
       track_name = QString::fromLatin1(buf.constData()).simplified();
       break;
     default:
@@ -169,14 +158,14 @@ ggv_bin_read_v2(QFile& file)
     switch (entry_type) {
     case 0x02:
       // text
-      ggv_bin_read16(file, "text color");
-      ggv_bin_read16(file, "text size");
-      ggv_bin_read16(file, "text trans");
-      ggv_bin_read16(file, "text font");
-      ggv_bin_read16(file, "text angle");
-      lon = ggv_bin_read_double(file, "text lon");
-      lat = ggv_bin_read_double(file, "text lat");
-      ggv_bin_read_text16(file, buf, "text label");
+      ggv_bin_read16(stream, "text color");
+      ggv_bin_read16(stream, "text size");
+      ggv_bin_read16(stream, "text trans");
+      ggv_bin_read16(stream, "text font");
+      ggv_bin_read16(stream, "text angle");
+      lon = ggv_bin_read_double(stream, "text lon");
+      lat = ggv_bin_read_double(stream, "text lat");
+      ggv_bin_read_text16(stream, buf, "text label");
       waypt_name = QString::fromLatin1(buf.constData()).simplified();
       wpt = new Waypoint;
       wpt->longitude = lon;
@@ -188,18 +177,18 @@ ggv_bin_read_v2(QFile& file)
       // line
     case 0x04:
       // area
-      ggv_bin_read16(file, "line color");
-      ggv_bin_read16(file, "line width");
-      ggv_bin_read16(file, "line type");
-      line_points = ggv_bin_read16(file, "line points");
+      ggv_bin_read16(stream, "line color");
+      ggv_bin_read16(stream, "line width");
+      ggv_bin_read16(stream, "line type");
+      line_points = ggv_bin_read16(stream, "line points");
       ggv_bin_track = route_head_alloc();
       track_add_head(ggv_bin_track);
       if (! track_name.isEmpty())
         ggv_bin_track->rte_name = track_name;
 
       for (int i = 1; i <= line_points; i++) {
-        lon = ggv_bin_read_double(file, "line lon");
-        lat = ggv_bin_read_double(file, "line lat");
+        lon = ggv_bin_read_double(stream, "line lon");
+        lat = ggv_bin_read_double(stream, "line lat");
         wpt = new Waypoint;
         wpt->longitude = lon;
         wpt->latitude = lat;
@@ -212,23 +201,23 @@ ggv_bin_read_v2(QFile& file)
       // circle
     case 0x07:
       // triangle
-      ggv_bin_read16(file, "geom color");
-      ggv_bin_read16(file, "geom prop1");
-      ggv_bin_read16(file, "geom prop2");
-      ggv_bin_read16(file, "geom angle");
-      ggv_bin_read16(file, "geom stroke");
-      ggv_bin_read16(file, "geom area");
-      ggv_bin_read_double(file, "geom lon");
-      ggv_bin_read_double(file, "geom lat");
+      ggv_bin_read16(stream, "geom color");
+      ggv_bin_read16(stream, "geom prop1");
+      ggv_bin_read16(stream, "geom prop2");
+      ggv_bin_read16(stream, "geom angle");
+      ggv_bin_read16(stream, "geom stroke");
+      ggv_bin_read16(stream, "geom area");
+      ggv_bin_read_double(stream, "geom lon");
+      ggv_bin_read_double(stream, "geom lat");
       break;
     case 0x09:
-      ggv_bin_read16(file, "bmp color");
-      ggv_bin_read16(file, "bmp prop1");
-      ggv_bin_read16(file, "bmp prop2");
-      ggv_bin_read16(file, "bmp prop3");
-      ggv_bin_read_double(file, "bmp lon");
-      ggv_bin_read_double(file, "bmp lat");
-      ggv_bin_read_text32(file, buf, "bmp data");
+      ggv_bin_read16(stream, "bmp color");
+      ggv_bin_read16(stream, "bmp prop1");
+      ggv_bin_read16(stream, "bmp prop2");
+      ggv_bin_read16(stream, "bmp prop3");
+      ggv_bin_read_double(stream, "bmp lon");
+      ggv_bin_read_double(stream, "bmp lat");
+      ggv_bin_read_text32(stream, buf, "bmp data");
       break;
     default:
       fatal(MYNAME ": Unknown entry type (0x%hx, pos=0x%llx) \n", entry_type, entry_pos);
@@ -241,24 +230,24 @@ ggv_bin_read_v2(QFile& file)
  ***************************************************************************/
 
 static void
-ggv_bin_read_v34_header(QFile& file, quint32& number_labels, quint32 &number_records)
+ggv_bin_read_v34_header(QDataStream& stream, quint32& number_labels, quint32 &number_records)
 {
   QByteArray buf;
   quint16 header_len;
     
-  ggv_bin_read_bytes(file, buf, 8, "unknown");
-  number_labels = ggv_bin_read32(file, "num labels");
-  number_records = ggv_bin_read32(file, "num records");
-  ggv_bin_read_text16(file, buf, "text label");
-  ggv_bin_read16(file, "unknown");
-  ggv_bin_read16(file, "unknown");
+  ggv_bin_read_bytes(stream, buf, 8, "unknown");
+  number_labels = ggv_bin_read32(stream, "num labels");
+  number_records = ggv_bin_read32(stream, "num records");
+  ggv_bin_read_text16(stream, buf, "text label");
+  ggv_bin_read16(stream, "unknown");
+  ggv_bin_read16(stream, "unknown");
   // 8 bytes ending with 1E 00, contains len of header block
-  ggv_bin_read16(file, "unknown");
-  header_len = ggv_bin_read16(file, "header len");
-  ggv_bin_read16(file, "unknown");
-  ggv_bin_read16(file, "unknown");
+  ggv_bin_read16(stream, "unknown");
+  header_len = ggv_bin_read16(stream, "header len");
+  ggv_bin_read16(stream, "unknown");
+  ggv_bin_read16(stream, "unknown");
   if (header_len > 0) {
-    ggv_bin_read_bytes(file, buf, header_len, "map name");
+    ggv_bin_read_bytes(stream, buf, header_len, "map name");
     buf.remove(0,4);
     buf.append('\0');
     if (global_opts.debug_level > 1)
@@ -267,52 +256,52 @@ ggv_bin_read_v34_header(QFile& file, quint32& number_labels, quint32 &number_rec
 }
 
 static void
-ggv_bin_read_v34_label(QFile& file)
+ggv_bin_read_v34_label(QDataStream& stream)
 {
   QByteArray buf;
 
   if (global_opts.debug_level > 1)
-    qDebug("------------------------------------ 0x%llx", file.pos());
-  ggv_bin_read_bytes(file, buf, 0x08, "label header");
-  ggv_bin_read_bytes(file, buf, 0x14, "label number");
-  ggv_bin_read_text16(file, buf, "label text");
-  ggv_bin_read16(file, "label flag1");
-  ggv_bin_read16(file, "label flag2");
+    qDebug("------------------------------------ 0x%llx", stream.device()->pos());
+  ggv_bin_read_bytes(stream, buf, 0x08, "label header");
+  ggv_bin_read_bytes(stream, buf, 0x14, "label number");
+  ggv_bin_read_text16(stream, buf, "label text");
+  ggv_bin_read16(stream, "label flag1");
+  ggv_bin_read16(stream, "label flag2");
 }
 
 static QString
-ggv_bin_read_v34_common(QFile& file)
+ggv_bin_read_v34_common(QDataStream& stream)
 {
   QByteArray buf;
   QString res;
   quint16 type1;
   quint16 type2;
   
-  ggv_bin_read16(file, "entry group");
-  ggv_bin_read16(file, "entry prop2");
-  ggv_bin_read16(file, "entry prop3");
-  ggv_bin_read16(file, "entry prop4");
-  ggv_bin_read16(file, "entry prop5");
-  ggv_bin_read16(file, "entry prop6");
-  ggv_bin_read16(file, "entry prop7");
-  ggv_bin_read16(file, "entry prop8");
-  ggv_bin_read16(file, "entry zoom");
-  ggv_bin_read16(file, "entry prop10");
-  ggv_bin_read_text16(file, buf, "entry txt");
+  ggv_bin_read16(stream, "entry group");
+  ggv_bin_read16(stream, "entry prop2");
+  ggv_bin_read16(stream, "entry prop3");
+  ggv_bin_read16(stream, "entry prop4");
+  ggv_bin_read16(stream, "entry prop5");
+  ggv_bin_read16(stream, "entry prop6");
+  ggv_bin_read16(stream, "entry prop7");
+  ggv_bin_read16(stream, "entry prop8");
+  ggv_bin_read16(stream, "entry zoom");
+  ggv_bin_read16(stream, "entry prop10");
+  ggv_bin_read_text16(stream, buf, "entry txt");
   res = QString::fromLatin1(buf.constData()).simplified();
-  type1 = ggv_bin_read16(file, "entry type1");
+  type1 = ggv_bin_read16(stream, "entry type1");
   if (type1 != 1) {
-    ggv_bin_read_text32(file, buf, "entry object");
+    ggv_bin_read_text32(stream, buf, "entry object");
   }
-  type2 = ggv_bin_read16(file, "entry type2");
+  type2 = ggv_bin_read16(stream, "entry type2");
   if (type2 != 1) {
-    ggv_bin_read_text32(file, buf, "entry object");
+    ggv_bin_read_text32(stream, buf, "entry object");
   }
   return res;
 }
 
 static void
-ggv_bin_read_v34_record(QFile& file)
+ggv_bin_read_v34_record(QDataStream& stream)
 {
   QByteArray buf;
   QString label;
@@ -324,26 +313,26 @@ ggv_bin_read_v34_record(QFile& file)
   double lon, lat;
 
   if (global_opts.debug_level > 1)
-    qDebug("------------------------------------ 0x%llx", file.pos());
+    qDebug("------------------------------------ 0x%llx", stream.device()->pos());
 
-  entry_type = ggv_bin_read16(file, "entry type");
-  label = ggv_bin_read_v34_common(file);
+  entry_type = ggv_bin_read16(stream, "entry type");
+  label = ggv_bin_read_v34_common(stream);
 
   switch (entry_type) {
   case 0x02:
     // text
-    ggv_bin_read16(file, "text prop1");
-    ggv_bin_read32(file, "text prop2");
-    ggv_bin_read16(file, "text prop3");
-    ggv_bin_read32(file, "text prop4");
-    ggv_bin_read16(file, "text ltype");
-    ggv_bin_read16(file, "text angle");
-    ggv_bin_read16(file, "text size");
-    ggv_bin_read16(file, "text area");
-    lon = ggv_bin_read_double(file, "text lon");
-    lat = ggv_bin_read_double(file, "text lat");
-    ggv_bin_read_double(file, "text unk");
-    ggv_bin_read_text16(file, buf, "text label");
+    ggv_bin_read16(stream, "text prop1");
+    ggv_bin_read32(stream, "text prop2");
+    ggv_bin_read16(stream, "text prop3");
+    ggv_bin_read32(stream, "text prop4");
+    ggv_bin_read16(stream, "text ltype");
+    ggv_bin_read16(stream, "text angle");
+    ggv_bin_read16(stream, "text size");
+    ggv_bin_read16(stream, "text area");
+    lon = ggv_bin_read_double(stream, "text lon");
+    lat = ggv_bin_read_double(stream, "text lat");
+    ggv_bin_read_double(stream, "text unk");
+    ggv_bin_read_text16(stream, buf, "text label");
     wpt = new Waypoint;
     wpt->longitude = lon;
     wpt->latitude = lat;
@@ -361,22 +350,22 @@ ggv_bin_read_v34_record(QFile& file)
     if (! label.isEmpty()) 
       ggv_bin_track->rte_name = label;
 
-    ggv_bin_read16(file, "line prop1");
-    ggv_bin_read32(file, "line prop2");
-    ggv_bin_read16(file, "line prop3");
-    ggv_bin_read32(file, "line color");
-    ggv_bin_read16(file, "line size");
-    ggv_bin_read16(file, "line stroke");
-    line_points = ggv_bin_read16(file, "line points");
+    ggv_bin_read16(stream, "line prop1");
+    ggv_bin_read32(stream, "line prop2");
+    ggv_bin_read16(stream, "line prop3");
+    ggv_bin_read32(stream, "line color");
+    ggv_bin_read16(stream, "line size");
+    ggv_bin_read16(stream, "line stroke");
+    line_points = ggv_bin_read16(stream, "line points");
     if (entry_type == 0x04) {
       // found in example.ovl generated by Geogrid-Viewer 1.0
-      ggv_bin_read16(file, "line pad");
+      ggv_bin_read16(stream, "line pad");
     }
 
     for (int i=1; i <= line_points; i++) {
-      lon = ggv_bin_read_double(file, "line lon");
-      lat = ggv_bin_read_double(file, "line lat");
-      ggv_bin_read_double(file, "line unk");
+      lon = ggv_bin_read_double(stream, "line lon");
+      lat = ggv_bin_read_double(stream, "line lat");
+      ggv_bin_read_double(stream, "line unk");
       wpt = new Waypoint;
       wpt->longitude = lon;
       wpt->latitude = lat;
@@ -387,34 +376,34 @@ ggv_bin_read_v34_record(QFile& file)
   case 0x06:
   case 0x07:
     // circle
-    ggv_bin_read16(file, "circle prop1");
-    ggv_bin_read32(file, "circle prop2");
-    ggv_bin_read16(file, "circle prop3");
-    ggv_bin_read32(file, "circle color");
-    ggv_bin_read32(file, "circle prop5");
-    ggv_bin_read32(file, "circle prop6");
-    ggv_bin_read16(file, "circle ltype");
-    ggv_bin_read16(file, "circle angle");
-    ggv_bin_read16(file, "circle size");
-    ggv_bin_read16(file, "circle area");
-    ggv_bin_read_double(file, "circle lon");
-    ggv_bin_read_double(file, "circle lat");
-    ggv_bin_read_double(file, "circle unk");
+    ggv_bin_read16(stream, "circle prop1");
+    ggv_bin_read32(stream, "circle prop2");
+    ggv_bin_read16(stream, "circle prop3");
+    ggv_bin_read32(stream, "circle color");
+    ggv_bin_read32(stream, "circle prop5");
+    ggv_bin_read32(stream, "circle prop6");
+    ggv_bin_read16(stream, "circle ltype");
+    ggv_bin_read16(stream, "circle angle");
+    ggv_bin_read16(stream, "circle size");
+    ggv_bin_read16(stream, "circle area");
+    ggv_bin_read_double(stream, "circle lon");
+    ggv_bin_read_double(stream, "circle lat");
+    ggv_bin_read_double(stream, "circle unk");
     break;
   case 0x09:
     // bmp
-    ggv_bin_read16(file, "bmp prop1");
-    ggv_bin_read32(file, "bmp prop2");
-    ggv_bin_read16(file, "bmp prop3");
-    ggv_bin_read32(file, "bmp prop4");
-    ggv_bin_read32(file, "bmp prop5");
-    ggv_bin_read32(file, "bmp prop6");
-    ggv_bin_read_double(file, "bmp lon");
-    ggv_bin_read_double(file, "bmp lat");
-    ggv_bin_read_double(file, "bmp unk");
-    bmp_len = ggv_bin_read32(file, "bmp len");
-    ggv_bin_read16(file, "bmp prop");
-    ggv_bin_read_bytes(file, buf, bmp_len, "bmp data");
+    ggv_bin_read16(stream, "bmp prop1");
+    ggv_bin_read32(stream, "bmp prop2");
+    ggv_bin_read16(stream, "bmp prop3");
+    ggv_bin_read32(stream, "bmp prop4");
+    ggv_bin_read32(stream, "bmp prop5");
+    ggv_bin_read32(stream, "bmp prop6");
+    ggv_bin_read_double(stream, "bmp lon");
+    ggv_bin_read_double(stream, "bmp lat");
+    ggv_bin_read_double(stream, "bmp unk");
+    bmp_len = ggv_bin_read32(stream, "bmp len");
+    ggv_bin_read16(stream, "bmp prop");
+    ggv_bin_read_bytes(stream, buf, bmp_len, "bmp data");
     break;
   default:
     fatal(MYNAME ": Unsupported type: %x\n", entry_type);
@@ -422,45 +411,45 @@ ggv_bin_read_v34_record(QFile& file)
 }
 
 static void
-ggv_bin_read_v34(QFile& file)
+ggv_bin_read_v34(QDataStream& stream)
 {
   QByteArray buf;
   QString track_name;
   quint32 label_count;
   quint32 record_count;
 
-  while (!file.atEnd()) {
-    ggv_bin_read_v34_header(file, label_count, record_count);
+  while (!stream.atEnd()) {
+    ggv_bin_read_v34_header(stream, label_count, record_count);
 
-    if (label_count && !file.atEnd()) {
+    if (label_count && !stream.atEnd()) {
       if (global_opts.debug_level > 1)
-        qDebug("-----labels------------------------- 0x%llx", file.pos());
+        qDebug("-----labels------------------------- 0x%llx", stream.device()->pos());
       for (unsigned int i = 0; i < label_count; i++)
-        ggv_bin_read_v34_label(file);
+        ggv_bin_read_v34_label(stream);
     }
 
-    if (record_count && !file.atEnd()) {
+    if (record_count && !stream.atEnd()) {
       if (global_opts.debug_level > 1)
-        qDebug("-----records------------------------ 0x%llx", file.pos());
+        qDebug("-----records------------------------ 0x%llx", stream.device()->pos());
       for (unsigned int i = 0; i < record_count; i++)
-        ggv_bin_read_v34_record(file);
+        ggv_bin_read_v34_record(stream);
     }
 
-    if (!file.atEnd()) {
+    if (!stream.atEnd()) {
       if (global_opts.debug_level > 1)
-        qDebug("------------------------------------ 0x%llx", file.pos());
+        qDebug("------------------------------------ 0x%llx", stream.device()->pos());
       // we just skip over the next magic bytes without checking they
       // contain the correct string. This is consistent with what I
       // believe GGV does
-      ggv_bin_read_bytes(file, buf, 23, "magicbytes");
+      ggv_bin_read_bytes(stream, buf, 23, "magicbytes");
       if (global_opts.debug_level > 1)
         qDebug() << "ovl: header = " << buf.constData();
     }
   }
     
   if (global_opts.debug_level > 1) {
-    qDebug("fpos: 0x%llx", file.pos());
-    qDebug("size: 0x%llx", file.size());
+    qDebug("fpos: 0x%llx", stream.device()->pos());
+    qDebug("size: 0x%llx", stream.device()->size());
   }
 }
 
@@ -469,22 +458,22 @@ ggv_bin_read_v34(QFile& file)
  ***************************************************************************/
 
 static void
-ggv_bin_read_file(QFile& file)
+ggv_bin_read_file(QDataStream& stream)
 {
   QByteArray buf;
 
-  ggv_bin_read_bytes(file, buf, 0x17, "magic");
+  ggv_bin_read_bytes(stream, buf, 0x17, "magic");
   buf[23] = 0;
   if (global_opts.debug_level > 1) {
     qDebug() << "ovl: header =" << buf.constData();
   }
 
   if (buf.startsWith("DOMGVCRD Ovlfile V2.0")) {
-    ggv_bin_read_v2(file);
+    ggv_bin_read_v2(stream);
   } else if (buf.startsWith("DOMGVCRD Ovlfile V3.0")) {
-    ggv_bin_read_v34(file);
+    ggv_bin_read_v34(stream);
   } else if (buf.startsWith("DOMGVCRD Ovlfile V4.0")) {
-    ggv_bin_read_v34(file);
+    ggv_bin_read_v34(stream);
   } else {
     fatal(MYNAME ": Unsupported file format\n");
   }
@@ -510,7 +499,11 @@ ggv_bin_read(void)
     fatal(MYNAME ": Error opening file %s\n", read_fname.toStdString().c_str());
   }
 
-  ggv_bin_read_file(file);
+  QDataStream stream(&file);
+  stream.setFloatingPointPrecision(QDataStream::DoublePrecision);
+  stream.setByteOrder(QDataStream::LittleEndian);
+  
+  ggv_bin_read_file(stream);
   file.close();
 }